/*
 * @lc app=leetcode.cn id=48 lang=typescript
 *
 * [48] 旋转图像
 */

// @lc code=start
/**
 Do not return anything, modify matrix in-place instead.
 */
/**
 * 以4角为例，没4个点为1组，进行旋转，只需要一个变量记录被替换的值即可
 * 这样，只需要遍历1/4矩阵（例如左上角），即可完成旋转
 * 可能要区分基数/偶数的n
 * 采坑：
 * 这个方案，在处理奇数n时。中间行或中间列上的点，进行且只进行一轮旋转（这里行循环i到floor, 列循环到ceil）
 */
function rotate(matrix: number[][]): void {
  let n = matrix.length
  // let centerNum: number = Math.ceil(n / 2) // 奇数n时，会浪费点性能(4次循环)，问题不大
  let i = 0,
    j = 0,
    replacedNum

  function getOrSet(i: number, j: number, v?: number): number {
    if (typeof v === 'number') {
      replacedNum = matrix[i][j]
      return (matrix[i][j] = v)
    } else {
      return matrix[i][j]
    }
  }
  function 左上角(i: number, j: number, v?: number): number {
    return getOrSet(i, j, v)
  }
  function 右上角(i: number, j: number, v?: number): number {
    return getOrSet(j , n - 1 - i, v)
  }
  function 右下角(i: number, j: number, v?: number): number {
    return getOrSet(n - 1 - i, n - 1 - j, v)
  }
  function 左下角(i: number, j: number, v?: number): number {
    return getOrSet(n - 1 - j, i, v)
  }

  // 原地替换，不用考虑初始化与越界
  for (; i < Math.floor(n / 2); i++) {
    for (j = 0; j < Math.ceil(n / 2); j++) {
      // 左下角替换左上角
      左上角(i, j, 左下角(i, j))
      // 左上角替换右上角
      右上角(i, j, replacedNum)
      // 右上角替换右下角
      右下角(i, j, replacedNum)
      // 右下角替换左下角
      左下角(i, j, replacedNum)
    }
  }
}
// @lc code=end

rotate([
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, 9],
])

rotate([
  [5, 1, 9, 11],
  [2, 4, 8, 10],
  [13, 3, 6, 7],
  [15, 14, 12, 16],
])

rotate([])